Categories
Node.js Tips

Node.js Tips — Async Functions, Read Files from S3, and Closing Servers

Spread the love

Like any kind of apps, there are difficult issues to solve when we write Node apps.

In this article, we’ll look at some solutions to common problems when writing Node apps.

Avoid the async/await Inside of a new Promise() Constructor Antipattern

We should avoid the asyhc and await inside of the Promise constructor antipattern.

For instance, instead of writing:

const createPromise = () => {
  return new Promise(async (resolve, reject) => {
    const val = await Promise.resolve(100);
    //..
  });
}

We don’t have to have an async function inside a promise because we shouldn’t have promises inside the Promise constructor.

async functions already return promises, so we don’t need the Promise constructor to turn the code into a promise.

We just move the async function out of the Promise and use that as is.

Update All Clients Using Socket.io

We can update all clients with socket.io by using the emit method.

For instance, we can write:

socket.emit('message', 'hello');

We emit the message event to all clients with the content 'hello' .

We can also use the io.sockets.emit method to emit to all sockets.

For instance, we can write:

io.sockets.emit('`message`', 'hello');

And we can use the broadcast property to do the same thing.

It sends a message to everyone except for the socket that’s sending the event:

socket.broadcast.emit('`message`', 'hello');

Get Response from S3 getObject in Node.js

We can call the getObject method to get the item we want as follows:

const aws = require('aws-sdk');
const s3 = new aws.S3();

const getParams = {
  Bucket: 'abc',
  Key: 'abc.txt'
}

s3.getObject(getParams, (err, data) => {
  if (err) {
    return err;
  }

  const objectData = data.Body.toString('utf-8');
});

We use the aws.S3 constructor to create a new client.

Then we set the parameters for setting the bucket and key, which is the file path.

Next, we call getObject to get the file with the given path in that bucket.

err is the error object.

data is the content of the file.

We convert it to a string with toString and the correct encoding.

Properly Close the Express Server

We call close on the http server instance rather than the app instance.

For instance, we can write:

app.get('/foo', (req, res) => {
  res.redirect('/');
  setTimeout(() => {
    server.close();
  }, 3000)
});

const server = app.listen(3000);

We call close on server , which is the http server instance.

app.listen returns the http server instance.

Calling a JSON API with Node.js

We can use the http module’s get method to make a GET request to a server.

For instance, we can write:

const url = 'https://api.agify.io/?name=michael';

http.get(url, (res) => {
  let body = '';
  res.on('data', (chunk) => {
    body += chunk;
  });

  res.on('end', () => {
    const response = JSON.parse(body);
    console.log(response.name);
  });
})
.on('error', (e) => {
  console.log(e);
});

We called get by passing in a callback.

The callback listens to the data event, which gets the data.

We listen to the end event to parse the JSON when the stream is done emitting data.

In the end callback, we parse the JSON with JSON.parse .

We also listen to the error event to log any errors if they exist.

Selecting Fields for Documents Populated in MongoDB

We can call the populate method to populate the field that we want and return it.

For instance, we can write:

Model
.findOne({ _id: '...' })
.populate('age', 'name')

We get the item by the _id , populate the age and return the name .

Check if a Function is async

We can check if a function is async by using the Symbol.toStringTag property.

For instance, we can write:

asyncFn[Symbol.toStringTag] === 'AsyncFunction'

We can also check if it’s an instance of the AsyncFunction with instanceof .

For instance, we can write:

const AsyncFunction = (async () => {}).constructor;
const isAsyncFunc = asyncFn instanceof AsyncFunction;

We get the constructor of the async function with the constructor property.

Then we use the instanceof operator to do the check.

Conclusion

We shouldn’t put async functions in the Promise constructor.

We can read a file from the S3 bucket with the getObject method.

Also, we can make HTTP requests with the http module.

We can call close on the http server instance returned by app.listen .

There are a few ways to check if a function is async.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *